﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml.Linq;
using BulldogCMS.Core.Storage.DataTypes;

namespace BulldogCMS.Core.Storage.Providers
{
    public abstract class BaseContentTreeProvider
    {
        protected void FillSimpleData(Node node, XDocument metaDoc)
        {
            if (metaDoc != null)
            {
                node.ID = metaDoc.Root.GetAttributeValue<long>("ID");
                node.Name = metaDoc.Root.GetAttributeValue<string>("name");
                node.TemplateName = metaDoc.Root.GetAttributeValue<string>("template");
                node.Mode = metaDoc.Root.GetAttributeValue<NodeMode>("mode");
                node.ContentProviderTypeName = metaDoc.Root.GetAttributeValue<string>("providerType");
                if (node.ContentProviderTypeName != null)
                {
                    node.ProviderRoot = true;
                    node.ContentTreeProvider = node.ContentProviderTypeName.Instantiate<IContentTreeProvider>();
                }
            }
        }

        protected void FillComplexData(Node node, XDocument metaDoc)
        {
            if (metaDoc != null)
            {
                if (metaDoc.Root.Element("parameters") != null && node.ContentTreeProvider != null)
                {
                    foreach (var parEl in metaDoc.Root.Element("parameters").Elements())
                    {
                        string parName = parEl.GetAttributeValue<string>("name");
                        string parValue = parEl.GetAttributeValue<string>("value");
                        node.ContentTreeProvider.SetParameter(parName, parValue);
                    }
                }

                XElement languagesEl = metaDoc.Root.Element("languages");
                if (languagesEl != null)
                {
                    node.VersionsMeta = new List<NodeVersionMeta>();
                    foreach (var languageEl in languagesEl.Elements())
                    {
                        foreach (var versionEl in languageEl.Elements())
                        {
                            NodeVersionMeta versionMeta = new NodeVersionMeta();
                            versionMeta.LanguageIdent = languageEl.GetAttributeValue<string>("ident");
                            versionMeta.VersionNumber = versionEl.GetAttributeValue<int>("number");
                            versionMeta.ID = versionEl.GetAttributeValue<int>("ID");
                            node.VersionsMeta.Add(versionMeta);
                        }
                    }
                }

                XElement sharedFieldsEl = metaDoc.Root.Element("sharedFields");
                if (sharedFieldsEl != null)
                {
                    List<BaseDataType> fields = new List<BaseDataType>();
                    foreach (var fieldEl in sharedFieldsEl.Elements())
                    {
                        string fieldName = fieldEl.GetAttributeValue<string>("name");
                        string fieldType = fieldEl.GetAttributeValue<string>("type");

                        BaseDataType field = fieldType.Instantiate<BaseDataType>();
                        field.Name = fieldName;
                        field.LoadFromXElement(fieldEl);
                        fields.Add(field);
                    }
                    node.SharedFields = fields;
                }
            }
        }

        protected void FillVersionSimpleData(NodeVersion version, XDocument versionDoc)
        {
            if (version != null)
            {
                version.ID = versionDoc.Root.GetAttributeValue<long>("ID");
                version.LanguageName = versionDoc.Root.GetAttributeValue<string>("language");
                version.VersionNumber = versionDoc.Root.GetAttributeValue<int>("version");
                version.ProcessState = NodeVersionStorageState.Loaded;
            }
        }

        protected void FillVersionComplexData(NodeVersion version, XDocument versionDoc)
        {
            XElement fieldsEl = versionDoc.Root.Element("fields");
            if (fieldsEl != null)
            {
                foreach (var fieldEl in fieldsEl.Elements("field"))
                {
                    string type = fieldEl.GetAttributeValue<string>("type");
                    string name = fieldEl.GetAttributeValue<string>("name");

                    BaseDataType field = type.Instantiate<BaseDataType>();
                    field.LoadFromXElement(fieldEl);
                    version.SetValue(name, field);
                }
            }
        }

        //protected NodeVersion ParseNodeVersion(XDocument versionDoc)
        //{
        //    NodeVersion nodeVersion = new NodeVersion()
        //    {
        //        ID = versionDoc.Root.GetAttributeValue<long>("ID"),
        //        LanguageName = versionDoc.Root.GetAttributeValue<string>("language"),
        //        VersionNumber = versionDoc.Root.GetAttributeValue<int>("version"),
        //        ProcessState = NodeVersionStorageState.Loaded,
        //    };

        //    XElement fieldsEl = versionDoc.Root.Element("fields");
        //    if (fieldsEl != null)
        //    {
        //        foreach (var fieldEl in fieldsEl.Elements("field"))
        //        {
        //            string type = fieldEl.GetAttributeValue<string>("type");
        //            string name = fieldEl.GetAttributeValue<string>("name");

        //            BaseDataType field = type.Instantiate<BaseDataType>();
        //            field.LoadFromXElement(fieldEl);
        //            nodeVersion.SetValue(name, field);
        //        }
        //    }
        //    return nodeVersion;
        //}

        //protected Node ParseMetaFile(dynamic metaObj)
        //{
        //    Node node = new Node();
        //    node.ID = metaObj.ID;
        //    node.TemplateName = metaObj.template;

        //    if (metaObj.Languages != null)
        //    {
        //        foreach (var languageObj in metaObj.Languages)
        //        {
        //            string langIdent = languageObj.ident;
        //            if (languageObj.versions != null)
        //            {
        //                node.VersionsMeta = new List<NodeVersionMeta>();
        //                foreach (var versionObj in languageObj.versions)
        //                {
        //                    NodeVersionMeta nodeVersionMeta = new NodeVersionMeta()
        //                    {
        //                        ID =                versionObj.ID,
        //                        LanguageIdent =     langIdent,
        //                        VersionNumber =     versionObj.number,
        //                        State =             Enum.Parse(typeof(NodeVersionState), versionObj.state),
        //                        PublishedOn =       DateTime.Parse(versionObj.publishedOn)
        //                    };
        //                    node.VersionsMeta.Add(nodeVersionMeta);
        //                }
        //            }
        //        }
        //    }

        //    return node;
        //}

        //protected NodeVersion ParseNodeVersion(dynamic versionObj)
        //{
        //    try
        //    {
        //        NodeVersion nodeVersion = new NodeVersion()
        //        {
        //            ID = versionObj.ID,
        //            LanguageName = versionObj.language,
        //            VersionNumber = versionObj.version
        //        };

        //        if (versionObj.fields != null)
        //        {
        //            foreach (var fieldObj in versionObj.fields)
        //            {
        //                string type = fieldObj.type;
        //                BaseDataType fieldObject = type.Instantiate<BaseDataType>();
        //            }
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        throw new ApplicationException("Parsing of JSON NodeVersion failed" ,ex);
        //    }
        //    return null;
        //}

    }
}